﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Utils.Drawing;
using System.Diagnostics;

namespace Utils.Drawing
{
    public class Sprite
    {
        public static readonly Vector2 ORIGIN_CENTER = new Vector2(0.5f, 0.5f);
        public static readonly Vector2 ORIGIN_TOP = new Vector2(0.5f, 0);
        public static readonly Vector2 ORIGIN_BOTTOM = new Vector2(0.5f, 1);
        public static readonly Vector2 ORIGIN_LEFT = new Vector2(0, 0.5f);
        public static readonly Vector2 ORIGIN_RIGHT = new Vector2(1, 0.5f);
        public static readonly Vector2 ORIGIN_TOP_LEFT = new Vector2(0, 0);
        public static readonly Vector2 ORIGIN_TOP_RIGHT = new Vector2(1, 0);
        public static readonly Vector2 ORIGIN_BOTTOM_LEFT = new Vector2(0, 1);
        public static readonly Vector2 ORIGIN_BOTTOM_RIGHT = new Vector2(1, 1);

        protected Texture2D texture;
        protected Vector2 position;
        protected Vector2 origin = ORIGIN_CENTER;
        protected Vector2 scale = Vector2.One;
        protected float rotation = 0f;
        protected Color color = Color.White;
        protected float alpha = 1f;
        protected BlendState blendState = BlendState.AlphaBlend;
        protected Effect effect;
        protected SpriteEffects spriteEffects = SpriteEffects.None;
        protected Rectangle? source = null;

        public Texture2D Texture { get { return texture; } set { texture = value; } }
        public Vector2 Position {   get { return position; }    set { position = value; } }
        public Vector2 Scale { get { return scale; } set { scale = value; } }
        public float ScaleF { set { scale.X = value; scale.Y = value; } }
        public float ScaleX { set { scale.X = value; } }
        public float ScaleY { set { scale.Y = value; } }
        public float Rotation { get { return rotation; } set { rotation = value; } }
        public Color Color { get { return color; } set { color = value; } }
        public float Alpha { get { return alpha; } set { alpha = value; } }
        public Vector2 Origin { get { return origin; } set { origin = value; } }
        public BlendState BlendState { get { return blendState; } set { blendState = value; } }
        public Effect Effect { get { return effect; } set { effect = value; } }
        public SpriteEffects SpriteEffects { get { return spriteEffects; } set { spriteEffects = value; } }
        public Rectangle? Source { get { return source; } set { source = value; } }

        public Sprite() { }

        public Sprite(Texture2D texture)
        {
            Debug.Assert(texture != null, "texture wasn't initialised");
            this.texture = texture;
        }

        public virtual void Draw(float dTime, SpriteRenderer spriteRenderer)
        {
            Color col;
            if (blendState == BlendState.AlphaBlend || blendState == SpriteRenderer.AdditivePremultiplied)
            {
                col = color * alpha;
            }
            else
            {
                col = color;
                col.A = (byte)(col.A * alpha);
            }

            Vector2 originVec = new Vector2();

            if (source != null)
            {
                originVec.X = origin.X * source.Value.Width;
                originVec.Y = origin.Y * source.Value.Height;
            }
            else
            {
                originVec.X = origin.X * texture.Width;
                originVec.Y = origin.Y * texture.Height;
            }

            spriteRenderer.Draw(
                texture, position, source, col, rotation, originVec,
                scale, blendState, effect, spriteEffects);
        }
    }
}
